home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / rogue / save.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-05-13  |  9.4 KB  |  393 lines

  1. /*
  2.  * save.c
  3.  *
  4.  * This source herein may be modified and/or distributed by anybody who
  5.  * so desires, with the following restrictions:
  6.  *    1.)  No portion of this notice shall be removed.
  7.  *    2.)  Credit shall not be taken for the creation of this source.
  8.  *    3.)  This code is not to be traded, sold, or used for personal
  9.  *         gain or profit.
  10.  *
  11.  */
  12.  
  13. #ifndef CURSES
  14. #include <curses.h>
  15. #endif CURSES
  16. #include <stdio.h>
  17. #include "rogue.h"
  18.  
  19. short write_failed = 0;
  20. char *save_file = "";
  21.  
  22. extern boolean detect_monster;
  23. extern short cur_level, max_level;
  24. extern char hunger_str[];
  25. extern char login_name[];
  26. extern short party_room;
  27. extern short party_counter;
  28. extern short foods;
  29. extern boolean is_wood[];
  30. extern short cur_room;
  31. extern boolean being_held;
  32. extern short bear_trap;
  33. extern short halluc;
  34. extern short blind;
  35. extern short confused;
  36. extern short levitate;
  37. extern short haste_self;
  38. extern boolean see_invisible;
  39. extern boolean detect_monster;
  40. extern boolean wizard;
  41. extern boolean score_only;
  42. extern short m_moves;
  43.  
  44. extern boolean msg_cleared;
  45.  
  46. save_game()
  47. {
  48.     char fname[64];
  49.  
  50.     if (!get_input_line("file name?", save_file, fname, "game not saved",
  51.             0, 1)) {
  52.         return;
  53.     }
  54.     check_message();
  55.     message(fname, 0);
  56.     save_into_file(fname);
  57. }
  58.  
  59. save_into_file(sfile)
  60. char *sfile;
  61. {
  62.     FILE *fp;
  63.     int file_id;
  64.     char name_buffer[80];
  65.     char *hptr;
  66.     struct rogue_time rt_buf;
  67.  
  68.     if (sfile[0] == '~') {
  69.         if (hptr = md_getenv("HOME")) {
  70.             (void) strcpy(name_buffer, hptr);
  71.             (void) strcat(name_buffer, sfile+1);
  72.             sfile = name_buffer;
  73.         }
  74.     }
  75.     if (    ((fp = fopen(sfile, "w")) == NULL) ||
  76.             ((file_id = md_get_file_id(sfile)) == -1)) {
  77.         message("problem accessing the save file", 0);
  78.         return;
  79.     }
  80.     md_ignore_signals();
  81.     write_failed = 0;
  82.     (void) xxx(1);
  83.     r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
  84.     r_write(fp, (char *) &cur_level, sizeof(cur_level));
  85.     r_write(fp, (char *) &max_level, sizeof(max_level));
  86.     write_string(hunger_str, fp);
  87.     write_string(login_name, fp);
  88.     r_write(fp, (char *) &party_room, sizeof(party_room));
  89.     r_write(fp, (char *) &party_counter, sizeof(party_counter));
  90.     write_pack(&level_monsters, fp);
  91.     write_pack(&level_objects, fp);
  92.     r_write(fp, (char *) &file_id, sizeof(file_id));
  93.     rw_dungeon(fp, 1);
  94.     r_write(fp, (char *) &foods, sizeof(foods));
  95.     r_write(fp, (char *) &rogue, sizeof(fighter));
  96.     write_pack(&rogue.pack, fp);
  97.     rw_id(id_potions, fp, POTIONS, 1);
  98.     rw_id(id_scrolls, fp, SCROLLS, 1);
  99.     rw_id(id_wands, fp, WANDS, 1);
  100.     rw_id(id_rings, fp, RINGS, 1);
  101.     r_write(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
  102.     r_write(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
  103.     r_write(fp, (char *) &cur_room, sizeof(cur_room));
  104.     rw_rooms(fp, 1);
  105.     r_write(fp, (char *) &being_held, sizeof(being_held));
  106.     r_write(fp, (char *) &bear_trap, sizeof(bear_trap));
  107.     r_write(fp, (char *) &halluc, sizeof(halluc));
  108.     r_write(fp, (char *) &blind, sizeof(blind));
  109.     r_write(fp, (char *) &confused, sizeof(confused));
  110.     r_write(fp, (char *) &levitate, sizeof(levitate));
  111.     r_write(fp, (char *) &haste_self, sizeof(haste_self));
  112.     r_write(fp, (char *) &see_invisible, sizeof(see_invisible));
  113.     r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
  114.     r_write(fp, (char *) &wizard, sizeof(wizard));
  115.     r_write(fp, (char *) &score_only, sizeof(score_only));
  116.     r_write(fp, (char *) &m_moves, sizeof(m_moves));
  117.     md_gct(&rt_buf);
  118.     rt_buf.second += 10;        /* allow for some processing time */
  119.     r_write(fp, (char *) &rt_buf, sizeof(rt_buf));
  120.     fclose(fp);
  121.  
  122.     if (write_failed) {
  123.         (void) md_df(sfile);    /* delete file */
  124.     } else {
  125.         clean_up("");
  126.     }
  127. }
  128.  
  129. restore(fname)
  130. char *fname;
  131. {
  132.     FILE *fp;
  133.     struct rogue_time saved_time, mod_time;
  134.     char buf[4];
  135.     char tbuf[40];
  136.     int new_file_id, saved_file_id;
  137.  
  138.     if (    ((new_file_id = md_get_file_id(fname)) == -1) ||
  139.             ((fp = fopen(fname, "r")) == NULL)) {
  140.         clean_up("cannot open file");
  141.     }
  142.     if (md_link_count(fname) > 1) {
  143.         clean_up("file has link");
  144.     }
  145.     (void) xxx(1);
  146.     r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
  147.     r_read(fp, (char *) &cur_level, sizeof(cur_level));
  148.     r_read(fp, (char *) &max_level, sizeof(max_level));
  149.     read_string(hunger_str, fp);
  150.  
  151.     (void) strcpy(tbuf, login_name);
  152.     read_string(login_name, fp);
  153.     if (strcmp(tbuf, login_name)) {
  154.         clean_up("you're not the original player");
  155.     }
  156.  
  157.     r_read(fp, (char *) &party_room, sizeof(party_room));
  158.     r_read(fp, (char *) &party_counter, sizeof(party_counter));
  159.     read_pack(&level_monsters, fp, 0);
  160.     read_pack(&level_objects, fp, 0);
  161.     r_read(fp, (char *) &saved_file_id, sizeof(saved_file_id));
  162.     if (new_file_id != saved_file_id) {
  163.         clean_up("sorry, saved game is not in the same file");
  164.     }
  165.     rw_dungeon(fp, 0);
  166.     r_read(fp, (char *) &foods, sizeof(foods));
  167.     r_read(fp, (char *) &rogue, sizeof(fighter));
  168.     read_pack(&rogue.pack, fp, 1);
  169.     rw_id(id_potions, fp, POTIONS, 0);
  170.     rw_id(id_scrolls, fp, SCROLLS, 0);
  171.     rw_id(id_wands, fp, WANDS, 0);
  172.     rw_id(id_rings, fp, RINGS, 0);
  173.     r_read(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
  174.     r_read(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
  175.     r_read(fp, (char *) &cur_room, sizeof(cur_room));
  176.     rw_rooms(fp, 0);
  177.     r_read(fp, (char *) &being_held, sizeof(being_held));
  178.     r_read(fp, (char *) &bear_trap, sizeof(bear_trap));
  179.     r_read(fp, (char *) &halluc, sizeof(halluc));
  180.     r_read(fp, (char *) &blind, sizeof(blind));
  181.     r_read(fp, (char *) &confused, sizeof(confused));
  182.     r_read(fp, (char *) &levitate, sizeof(levitate));
  183.     r_read(fp, (char *) &haste_self, sizeof(haste_self));
  184.     r_read(fp, (char *) &see_invisible, sizeof(see_invisible));
  185.     r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
  186.     r_read(fp, (char *) &wizard, sizeof(wizard));
  187.     r_read(fp, (char *) &score_only, sizeof(score_only));
  188.     r_read(fp, (char *) &m_moves, sizeof(m_moves));
  189.     r_read(fp, (char *) &saved_time, sizeof(saved_time));
  190.  
  191.     if (fread(buf, sizeof(char), 1, fp) > 0) {
  192.         clear();
  193.         clean_up("extra characters in file");
  194.     }
  195.  
  196.     md_gfmt(fname, &mod_time);    /* get file modification time */
  197.  
  198.     if (has_been_touched(&saved_time, &mod_time)) {
  199.         clear();
  200.         clean_up("sorry, file has been touched");
  201.     }
  202.     if ((!wizard) && !md_df(fname)) {
  203.         clean_up("cannot delete file");
  204.     }
  205.     msg_cleared = 0;
  206.     ring_stats(0);
  207.     fclose(fp);
  208. }
  209.  
  210. write_pack(pack, fp)
  211. object *pack;
  212. FILE *fp;
  213. {
  214.     object t;
  215.  
  216.     while (pack = pack->next_object) {
  217.         r_write(fp, (char *) pack, sizeof(object));
  218.     }
  219.     t.ichar = t.what_is = 0;
  220.     r_write(fp, (char *) &t, sizeof(object));
  221. }
  222.  
  223. read_pack(pack, fp, is_rogue)
  224. object *pack;
  225. FILE *fp;
  226. boolean is_rogue;
  227. {
  228.     object read_obj, *new_obj;
  229.  
  230.     for (;;) {
  231.         r_read(fp, (char *) &read_obj, sizeof(object));
  232.         if (read_obj.ichar == 0) {
  233.             pack->next_object = (object *) 0;
  234.             break;
  235.         }
  236.         new_obj = alloc_object();
  237.         *new_obj = read_obj;
  238.         if (is_rogue) {
  239.             if (new_obj->in_use_flags & BEING_WORN) {
  240.                     do_wear(new_obj);
  241.             } else if (new_obj->in_use_flags & BEING_WIELDED) {
  242.                     do_wield(new_obj);
  243.             } else if (new_obj->in_use_flags & (ON_EITHER_HAND)) {
  244.                 do_put_on(new_obj,
  245.                     ((new_obj->in_use_flags & ON_LEFT_HAND) ? 1 : 0));
  246.             }
  247.         }
  248.         pack->next_object = new_obj;
  249.         pack = new_obj;
  250.     }
  251. }
  252.  
  253. rw_dungeon(fp, rw)
  254. FILE *fp;
  255. boolean rw;
  256. {
  257.     short i, j;
  258.     char buf[DCOLS];
  259.  
  260.     for (i = 0; i < DROWS; i++) {
  261.         if (rw) {
  262.             r_write(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
  263.             for (j = 0; j < DCOLS; j++) {
  264.                 buf[j] = mvinch(i, j);
  265.             }
  266.             r_write(fp, buf, DCOLS);
  267.         } else {
  268.             r_read(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
  269.             r_read(fp, buf, DCOLS);
  270.             for (j = 0; j < DCOLS; j++) {
  271.                 mvaddch(i, j, buf[j]);
  272.             }
  273.         }
  274.     }
  275. }
  276.  
  277. rw_id(id_table, fp, n, wr)
  278. struct id id_table[];
  279. FILE *fp;
  280. int n;
  281. boolean wr;
  282. {
  283.     short i;
  284.  
  285.     for (i = 0; i < n; i++) {
  286.         if (wr) {
  287.             r_write(fp, (char *) &(id_table[i].value), sizeof(short));
  288.             r_write(fp, (char *) &(id_table[i].id_status),
  289.                 sizeof(unsigned short));
  290.             write_string(id_table[i].title, fp);
  291.         } else {
  292.             r_read(fp, (char *) &(id_table[i].value), sizeof(short));
  293.             r_read(fp, (char *) &(id_table[i].id_status),
  294.                 sizeof(unsigned short));
  295.             read_string(id_table[i].title, fp);
  296.         }
  297.     }
  298. }
  299.  
  300. write_string(s, fp)
  301. char *s;
  302. FILE *fp;
  303. {
  304.     short n;
  305.  
  306.     n = strlen(s) + 1;
  307.     xxxx(s, n);
  308.     r_write(fp, (char *) &n, sizeof(short));
  309.     r_write(fp, s, n);
  310. }
  311.  
  312. read_string(s, fp)
  313. char *s;
  314. FILE *fp;
  315. {
  316.     short n;
  317.  
  318.     r_read(fp, (char *) &n, sizeof(short));
  319.     r_read(fp, s, n);
  320.     xxxx(s, n);
  321. }
  322.  
  323. rw_rooms(fp, rw)
  324. FILE *fp;
  325. boolean rw;
  326. {
  327.     short i;
  328.  
  329.     for (i = 0; i < MAXROOMS; i++) {
  330.         rw ? r_write(fp, (char *) (rooms + i), sizeof(room)) :
  331.             r_read(fp, (char *) (rooms + i), sizeof(room));
  332.     }
  333. }
  334.  
  335. r_read(fp, buf, n)
  336. FILE *fp;
  337. char *buf;
  338. int n;
  339. {
  340.     if (fread(buf, sizeof(char), n, fp) != n) {
  341.         clean_up("read() failed, don't know why");
  342.     }
  343. }
  344.  
  345. r_write(fp, buf, n)
  346. FILE *fp;
  347. char *buf;
  348. int n;
  349. {
  350.     if (!write_failed) {
  351.         if (fwrite(buf, sizeof(char), n, fp) != n) {
  352.             message("write() failed, don't know why", 0);
  353.             sound_bell();
  354.             write_failed = 1;
  355.         }
  356.     }
  357. }
  358.  
  359. boolean
  360. has_been_touched(saved_time, mod_time)
  361. struct rogue_time *saved_time, *mod_time;
  362. {
  363.     if (saved_time->year < mod_time->year) {
  364.         return(1);
  365.     } else if (saved_time->year > mod_time->year) {
  366.         return(0);
  367.     }
  368.     if (saved_time->month < mod_time->month) {
  369.         return(1);
  370.     } else if (saved_time->month > mod_time->month) {
  371.         return(0);
  372.     }
  373.     if (saved_time->day < mod_time->day) {
  374.         return(1);
  375.     } else if (saved_time->day > mod_time->day) {
  376.         return(0);
  377.     }
  378.     if (saved_time->hour < mod_time->hour) {
  379.         return(1);
  380.     } else if (saved_time->hour > mod_time->hour) {
  381.         return(0);
  382.     }
  383.     if (saved_time->minute < mod_time->minute) {
  384.         return(1);
  385.     } else if (saved_time->minute > mod_time->minute) {
  386.         return(0);
  387.     }
  388.     if (saved_time->second < mod_time->second) {
  389.         return(1);
  390.     }
  391.     return(0);
  392. }
  393.